////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
//  File name:   SequenceObject.cpp
//  Version:     v1.00
//  Created:     05/02/2005 by Sergiy Shaykin.
//  Compilers:   Visual C++ 6.0
//  Description: CSequenceObject implementation.
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#include "StdAfx.h"

#include "EntityObject.h"
#include "Geometry\EdMesh.h"
#include "Material\Material.h"
#include "Material\MaterialManager.h"
#include "CryEditDoc.h"

#include <IEntitySystem.h>
#include <IEntityRenderState.h>


#include "SequenceObject.h"
#include "ProceduralSystem/ProceduralCreation.h"



//////////////////////////////////////////////////////////////////////////
// CSequenceObject implementation.
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CSequenceObject,CBaseObject)


//////////////////////////////////////////////////////////////////////////
CSequenceObject::CSequenceObject()
{
	m_pSequence = 0;
	m_bValidSettings = false;
}


//////////////////////////////////////////////////////////////////////////
bool CSequenceObject::Init( IEditor *ie,CBaseObject *prev,const CString &file )
{
	// A SequenceObject cannot be cloned.
	if (prev)
		return false;

	SetColor( RGB(127,127,255) );

	if(!file.IsEmpty())
		SetName(file);

	SetTextureIcon( GetClassDesc()->GetTextureIconId() );

	// Must be after SetSequence call.
	bool res = CBaseObject::Init( ie,prev,file );
	
	return res;
}

//////////////////////////////////////////////////////////////////////////
bool CSequenceObject::CreateGameObject()
{
	if(!m_pSequence)
	{
		m_pSequence = GetIEditor()->GetMovieSystem()->FindSequence(GetName());
		if(!m_pSequence)
			m_pSequence = GetIEditor()->GetMovieSystem()->CreateSequence(GetName(), NULL, true);
		m_pSequence->SetOwner(this);
		GetIEditor()->Notify(eNotify_OnUpdateTrackView);
	}

	return true;
}

//////////////////////////////////////////////////////////////////////////
void CSequenceObject::Done()
{
	assert(m_pSequence);

	if(m_pSequence)
	{
		GetIEditor()->GetMovieSystem()->RemoveSequence(m_pSequence);
		m_pSequence->SetOwner(NULL);
	}

	m_pSequence = 0;
	
	GetIEditor()->Notify(eNotify_OnUpdateTrackView);
	
	CBaseObject::Done();
}

//////////////////////////////////////////////////////////////////////////
void CSequenceObject::SetName( const CString &name )
{
	if(!m_pSequence)
	{
		CBaseObject::SetName(name);
		return;
	}

	// If it has a valid sequence, the name cannot be edited through this.
}

void CSequenceObject::OnModified()
{
	assert(m_pSequence);

	if(m_pSequence)
	{
		string fullname = m_pSequence->GetFullName();
		CBaseObject::SetName(fullname.c_str());
		SetLayerModified();
	}
}

//////////////////////////////////////////////////////////////////////////
void CSequenceObject::GetBoundBox( AABB &box )
{
	box.SetTransformedAABB( GetWorldTM(),AABB(Vec3(-1,-1,-1),Vec3(1,1,1)) );
}

//////////////////////////////////////////////////////////////////////////
void CSequenceObject::GetLocalBounds( AABB &box )
{
	box.min = Vec3(-1,-1,-1);
	box.max = Vec3(1,1,1);
}


//////////////////////////////////////////////////////////////////////////
void CSequenceObject::Display( DisplayContext &dc )
{
	/*
	const Matrix34 &wtm = GetWorldTM();
	Vec3 wp = wtm.GetTranslation();

	if (IsSelected())
		dc.SetSelectedColor();
	else if (IsFrozen())
		dc.SetFreezeColor();
	else
		dc.SetColor( GetColor() );

	dc.PushMatrix( wtm );
	BBox box;
	GetLocalBounds(box);
	dc.DrawWireBox( box.min,box.max);
	dc.PopMatrix();
	*/

	DrawDefault( dc );
}


//////////////////////////////////////////////////////////////////////////
void CSequenceObject::Serialize( CObjectArchive &ar )
{
	CBaseObject::Serialize( ar );

	if (ar.bLoading)
	{
		XmlNodeRef settingsNode = ar.node->findChild("ZoomScrollSettings");
		if (settingsNode)
		{
			if (m_zoomScrollSettings.Load(settingsNode))
				m_bValidSettings = true;
		}
	}
	else
	{
		assert(m_pSequence);
		if(m_pSequence)
		{
			XmlNodeRef sequenceNode=ar.node->newChild("Sequence");
			m_pSequence->Serialize(sequenceNode, false);
			
			XmlNodeRef settingsNode = ar.node->newChild("ZoomScrollSettings");
			m_zoomScrollSettings.Save(settingsNode);
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CSequenceObject::PostLoad( CObjectArchive &ar )
{
	XmlNodeRef sequenceNode = ar.node->findChild("Sequence");
	if (m_pSequence != NULL && sequenceNode != NULL)
	{
		m_pSequence->Serialize(sequenceNode, true);
		GetIEditor()->Notify(eNotify_OnUpdateTrackView);
	}
}

//////////////////////////////////////////////////////////////////////////
void CSequenceObject::CZoomScrollSettings::Save(XmlNodeRef node) const
{
	node->setAttr("dopeSheetZoom", dopeSheetZoom);
	node->setAttr("dopeSheetHScroll", dopeSheetHScroll);
	node->setAttr("nodesListVScroll", nodesListVScroll);
	node->setAttr("curveEditorZoom", curveEditorZoom);
	node->setAttr("curveEditorScroll", curveEditorScroll);
}

//////////////////////////////////////////////////////////////////////////
bool CSequenceObject::CZoomScrollSettings::Load(XmlNodeRef node)
{
	if (node->getAttr("dopeSheetZoom", dopeSheetZoom) == false)
		return false;
	if (node->getAttr("dopeSheetHScroll", dopeSheetHScroll) == false)
		return false;
	if (node->getAttr("nodesListVScroll", nodesListVScroll) == false)
		return false;
	if (node->getAttr("curveEditorZoom", curveEditorZoom) == false)
		return false;
	if (node->getAttr("curveEditorScroll", curveEditorScroll) == false)
		return false;

	return true;
}